use anyhow::Result;
use dotenv::dotenv;
use teloxide::{dispatching2::UpdateFilterExt, prelude2::*, types::Update};

mod db;
mod handlers;
mod helpers;
mod keyboards;
mod post;
mod user;

#[tokio::main]
async fn main() {
    dotenv().ok();
    run_bot().await;
}

use teloxide::utils::command::BotCommand;
#[derive(BotCommand, Debug)]
#[command(rename = "lowercase")]
enum Command {
    Start,
    Random,
    CountUnread,
    GetAllPosts,
    Collections,
}
async fn command_answer(bot: AutoSend<Bot>, m: Message, command: Command) -> Result<()> {
    match command {
        Command::Start => {
            handlers::start(bot, m).await?;
            Ok(())
        }
        Command::Random => {
            handlers::random(bot, m).await?;
            Ok(())
        }
        Command::CountUnread => {
            handlers::count_unread_posts_handler(bot, m).await?;
            Ok(())
        }
        Command::GetAllPosts => {
            handlers::get_all_posts(bot, m).await?;
            Ok(())
        }
        Command::Collections => {
            handlers::get_all_collections(bot, m).await?;
            Ok(())
        }
    }
}
pub async fn messages_handler(m: Message, bot: AutoSend<Bot>) -> Result<()> {
    if let Some(text) = parse_text(&m) {
        if let Ok(command) = BotCommand::parse(&text, "readlaterbot") {
            command_answer(bot, m, command).await?;
        } else {
            handlers::add(bot, m).await?;
        }
    }
    Ok(())
}
fn parse_text(m: &Message) -> Option<String> {
    let mut res = None;
    if let Some(text) = m.text() {
        res = Some(text.to_string());
    }
    if let Some(text) = m.caption() {
        res = Some(text.to_string());
    }
    res
}

async fn handle_callback_query(q: CallbackQuery, bot: AutoSend<Bot>) -> Result<()> {
    let data = q.data.clone();
    match data {
        None => {}
        Some(data) => {
            // TODO: ref using enums
            if data.starts_with("del") {
                crate::handlers::delete(bot, q, data.strip_prefix("del ").unwrap()).await?;
            } else if data.starts_with("archive") {
                crate::handlers::archive(bot, q, data.strip_prefix("archive ").unwrap()).await?;
            } else if data.starts_with("unarchive") {
                crate::handlers::unarchive(bot, q, data.strip_prefix("unarchive ").unwrap())
                    .await?;
            } else if data.starts_with("page") {
                crate::handlers::change_page(bot, q, data.strip_prefix("page ").unwrap()).await?;
            } else if data.starts_with("post") {
                crate::handlers::get_post_info(bot, q, data.strip_prefix("post ").unwrap()).await?;
            }
        }
    }
    Ok(())
}
async fn run_bot() {
    teloxide::enable_logging!();
    log::info!("Starting readlaterbot...");

    let bot = teloxide::Bot::new(std::env::var("TELEGRAM_BOT_TOKEN").unwrap()).auto_send();

    let handler = dptree::entry()
        //.branch(Update::filter_message().filter_command::<Command>().endpoint(command_answer))
        .branch(Update::filter_message().endpoint(messages_handler))
        .branch(Update::filter_callback_query().endpoint(handle_callback_query));
    Dispatcher::builder(bot, handler)
        .build()
        .setup_ctrlc_handler()
        .dispatch()
        .await;
}
